@@ -0,0 +1,3 @@ |
||
1 |
+# Place all the behaviors and hooks related to the matching controller here. |
|
2 |
+# All this logic will automatically be available in application.js. |
|
3 |
+# You can use CoffeeScript in this file: http://coffeescript.org/ |
@@ -0,0 +1,3 @@ |
||
1 |
+// Place all the styles related to the subscription controller here. |
|
2 |
+// They will automatically be included in application.css. |
|
3 |
+// You can use Sass (SCSS) here: http://sass-lang.com/ |
@@ -30,6 +30,18 @@ class AdminPanelController < ApplicationController |
||
30 | 30 |
def show_contact_message |
31 | 31 |
@msg = ContactMessage.find(params[:id]) |
32 | 32 |
end |
33 |
+ |
|
34 |
+ def subscribers |
|
35 |
+ @subscribers = Subscription.all |
|
36 |
+ end |
|
37 |
+ |
|
38 |
+ def export_subscribers_list |
|
39 |
+ @subscribers = Subscription.all |
|
40 |
+ respond_to do |format| |
|
41 |
+ format.html |
|
42 |
+ format.csv { render text: @subscribers.to_csv } |
|
43 |
+ end |
|
44 |
+ end |
|
33 | 45 |
|
34 | 46 |
def users |
35 | 47 |
@users = User.order('created_at DESC').all |
@@ -1,4 +1,5 @@ |
||
1 | 1 |
class ApplicationController < ActionController::Base |
2 |
+ |
|
2 | 3 |
# Prevent CSRF attacks by raising an exception. |
3 | 4 |
# For APIs, you may want to use :null_session instead. |
4 | 5 |
|
@@ -2,6 +2,7 @@ class StartController < ApplicationController |
||
2 | 2 |
|
3 | 3 |
def index |
4 | 4 |
@blog_posts = BlogPost.order('created_at DESC').take(4) |
5 |
+ @subscription = Subscription.new |
|
5 | 6 |
end |
6 | 7 |
|
7 | 8 |
end |
@@ -0,0 +1,21 @@ |
||
1 |
+class SubscriptionController < ApplicationController |
|
2 |
+ def create |
|
3 |
+ @subscription = Subscription.new(subscription_params) |
|
4 |
+ respond_to do |format| |
|
5 |
+ if @subscription.save |
|
6 |
+ UserMailer.newsletter_subscription(@subscription).deliver |
|
7 |
+ format.html { redirect_to root_path, notice: 'Thanks for subscribing to our newsletter' } |
|
8 |
+ format.json { render action: 'show', status: :created, location: @subscription } |
|
9 |
+ else |
|
10 |
+ format.html { redirect_to root_path, alert: 'An error ocured. Please try gain.' } |
|
11 |
+ format.json { render json: @subscription.errors, status: :unprocessable_entity } |
|
12 |
+ end |
|
13 |
+ end |
|
14 |
+ end |
|
15 |
+ |
|
16 |
+ # Never trust parameters from the scary internet, only allow the white list through. |
|
17 |
+ def subscription_params |
|
18 |
+ params.require(:subscription).permit(:first_name, :last_name, :email) |
|
19 |
+ end |
|
20 |
+ |
|
21 |
+end |
@@ -0,0 +1,2 @@ |
||
1 |
+module SubscriptionHelper |
|
2 |
+end |
@@ -11,4 +11,13 @@ class UserMailer < ActionMailer::Base |
||
11 | 11 |
:body => @msg.content |
12 | 12 |
end |
13 | 13 |
|
14 |
+ def newsletter_subscription(subscription) |
|
15 |
+ config = Info.first |
|
16 |
+ mail :to => subscription.email, |
|
17 |
+ :subject => (t 'newsletter_subscription.subject'), |
|
18 |
+ :from => config.contact_email, |
|
19 |
+ :from_name => config.website_name, |
|
20 |
+ :body => (t 'newsletter_subscription.message') |
|
21 |
+ end |
|
22 |
+ |
|
14 | 23 |
end |
@@ -0,0 +1,16 @@ |
||
1 |
+class Subscription < ActiveRecord::Base |
|
2 |
+ |
|
3 |
+ def full_name |
|
4 |
+ return self.first_name + " " + self.last_name |
|
5 |
+ end |
|
6 |
+ |
|
7 |
+ def self.to_csv |
|
8 |
+ CSV.generate do |csv| |
|
9 |
+ csv << column_names |
|
10 |
+ all.each do |product| |
|
11 |
+ csv << product.attributes.values_at(*column_names) |
|
12 |
+ end |
|
13 |
+ end |
|
14 |
+ end |
|
15 |
+ |
|
16 |
+end |
@@ -16,6 +16,9 @@ |
||
16 | 16 |
<% if current_page?(:action => 'users')%><li class="active"> <% else %><li><% end %> |
17 | 17 |
<%= link_to ('<i class="fa fa-users fa-fw"></i> '+(t "admin_panel.users")).html_safe, admin_users_path %></li> |
18 | 18 |
|
19 |
+ <% if current_page?(:action => 'subscribers')%><li class="active"> <% else %><li><% end %> |
|
20 |
+ <%= link_to ('<i class="fa fa-newspaper-o"></i> '+(t "admin_panel.subscribers")).html_safe, admin_subscribers_path %></li> |
|
21 |
+ |
|
19 | 22 |
<% if current_page?(:action => 'site_config')%><li class="active"> <% else %><li><% end %> |
20 | 23 |
<%= link_to ('<i class="fa fa-cog fa-fw"></i> '+(t "admin_panel.configurations")).html_safe, admin_config_path %></li> |
21 | 24 |
|
@@ -0,0 +1,32 @@ |
||
1 |
+<div class="row"> |
|
2 |
+ <%= render 'admin_panel/sidebar_nav' %> |
|
3 |
+ <div class="span9"> |
|
4 |
+ <div class="page-header"> |
|
5 |
+ <h1> |
|
6 |
+ <i class="fa fa-envelope"></i> |
|
7 |
+ <%= t "admin_panel.subscribers" %> <%= link_to (t "subscription.export"), export_subscribers_list_path(format: :csv), class: 'btn btn-primary btn-mini pull-right', style: 'margin-top: 10px' %> |
|
8 |
+ </h1> |
|
9 |
+ </div> |
|
10 |
+ <%= bootstrap_flash %> |
|
11 |
+ |
|
12 |
+ <table class="table table-bordered"> |
|
13 |
+ <thead> |
|
14 |
+ <tr> |
|
15 |
+ <th>Name</th> |
|
16 |
+ <th>Email</th> |
|
17 |
+ <th>Registered</th> |
|
18 |
+ </tr> |
|
19 |
+ </thead> |
|
20 |
+ <tbody> |
|
21 |
+ <% @subscribers.each do |subscription| %> |
|
22 |
+ <tr> |
|
23 |
+ <td><%= subscription.full_name %></td> |
|
24 |
+ <td><%= subscription.email %></td> |
|
25 |
+ <td><%= time_ago_in_words(subscription.created_at) %></td> |
|
26 |
+ </tr> |
|
27 |
+ <% end %> |
|
28 |
+ </tbody> |
|
29 |
+ </table> |
|
30 |
+ </div> |
|
31 |
+</div> |
|
32 |
+ |
@@ -0,0 +1,14 @@ |
||
1 |
+<h3><%= (t 'subscription.header')%></h3> |
|
2 |
+<%= bootstrap_form_for(@subscription) do |f| %> |
|
3 |
+ <%= f.alert_message "Please fix the errors below."%> |
|
4 |
+ <%= f.form_group :first_name do %> |
|
5 |
+ <%= f.text_field :first_name, label: (t 'registration.first_name'), class: 'input-block-level', required: true %> |
|
6 |
+ <% end %> |
|
7 |
+ <%= f.form_group :last_name do %> |
|
8 |
+ <%= f.text_field :last_name, label: (t 'registration.last_name'), class: 'input-block-level', required: true %> |
|
9 |
+ <% end %> |
|
10 |
+ <%= f.form_group :email do %> |
|
11 |
+ <%= f.text_field :email, label: (t 'registration.email'), class: 'input-block-level', required: true %> |
|
12 |
+ <% end %> |
|
13 |
+ <%= f.submit (t 'subscription.submit'), class: 'btn btn-success', id: 'submit_subscription' %> |
|
14 |
+<% end %> |
@@ -25,3 +25,4 @@ |
||
25 | 25 |
|
26 | 26 |
|
27 | 27 |
<br> |
28 |
+<%= render 'layouts/subscribe_to_newsletter' %> |
@@ -1,5 +1,6 @@ |
||
1 | 1 |
require File.expand_path('../boot', __FILE__) |
2 | 2 |
|
3 |
+require 'csv' |
|
3 | 4 |
require 'rails/all' |
4 | 5 |
|
5 | 6 |
# Require the gems listed in Gemfile, including any gems |
@@ -4,4 +4,7 @@ en: |
||
4 | 4 |
reset_text: Someone has requested a link to change your password. You can do this through the link below. |
5 | 5 |
change_my_password: Change my password |
6 | 6 |
not_requested: "If you didn't request this, please ignore this email." |
7 |
- password_will_not_change: "Your password won't change until you access the link above and create a new one." |
|
7 |
+ password_will_not_change: "Your password won't change until you access the link above and create a new one." |
|
8 |
+ newsletter_subscription: |
|
9 |
+ subject: Thanks for subscribing |
|
10 |
+ message: Welcome to our website |
@@ -5,4 +5,6 @@ pt-BR: |
||
5 | 5 |
change_my_password: Trocar minha senha |
6 | 6 |
not_requested: "Se você não solicitou a mudança de senha, por favor ignore este email." |
7 | 7 |
password_will_not_change: Sua senha não vai mudar a não ser que você crie uma nova. |
8 |
- |
|
8 |
+ newsletter_subscription: |
|
9 |
+ subject: Bem vindo |
|
10 |
+ message: Obrigado por se inscrever na nossa newsletter! |
@@ -295,4 +295,9 @@ en: |
||
295 | 295 |
change_password: Save Password |
296 | 296 |
cancel_account: Delete Account |
297 | 297 |
cancel_confirmation: Are you sure you want to delete your account permenantly? |
298 |
- edit_password: Edit password |
|
298 |
+ edit_password: Edit password |
|
299 |
+ subscription: |
|
300 |
+ subscribers: Subscribers |
|
301 |
+ header: Subscribe to our newsletter |
|
302 |
+ submit: Subscribe |
|
303 |
+ export: Export CVS |
@@ -299,4 +299,9 @@ pt-BR: |
||
299 | 299 |
update: Atualizar |
300 | 300 |
cancel_account: Cancelar Conta |
301 | 301 |
cancel_confirmation: Você tem certeza que deseja cancelar sua conta? |
302 |
- edit_password: Editar senha |
|
302 |
+ edit_password: Editar senha |
|
303 |
+ subscription: |
|
304 |
+ subscribers: Seguidores |
|
305 |
+ header: Receba nossa newsletter |
|
306 |
+ submit: Enviar |
|
307 |
+ export: Exportart CVS |
@@ -1,11 +1,15 @@ |
||
1 | 1 |
RailsWebsiteTemplate::Application.routes.draw do |
2 | 2 |
|
3 |
+ root 'start#index' |
|
3 | 4 |
|
5 |
+ get "subscription/create" |
|
4 | 6 |
resources :contact_messages, path: '/contact', :as => :contact_messages |
5 | 7 |
|
6 | 8 |
resources :uploads |
7 | 9 |
|
8 | 10 |
get "maintenance_mode" => "admin_panel#maintenance_mode", :as => :maintenance_mode |
11 |
+ |
|
12 |
+ post "subscribe" => "subscription#create", :as => :subscriptions |
|
9 | 13 |
|
10 | 14 |
get "admin/dashboard" => "admin_panel#dashboard", :as => :admin_dashboard |
11 | 15 |
get "admin" => "admin_panel#index" |
@@ -13,7 +17,9 @@ RailsWebsiteTemplate::Application.routes.draw do |
||
13 | 17 |
get "admin/contact_messages" => "admin_panel#contact_messages", :as => :admin_contact_messages |
14 | 18 |
get "admin/contact_message/:id" => "admin_panel#show_contact_message", :as => :show_contact_message |
15 | 19 |
get "admin/contact_message/:id/mark_contact_message_as_readed" => "contact_messages#readed", :as => :mark_contact_message_as_readed |
16 |
- get "admin/contact_message/:id/mark_contact_message_as_unread" => "contact_messages#unread", :as => :mark_contact_message_as_unread |
|
20 |
+ get "admin/contact_message/:id/mark_contact_message_as_unread" => "contact_messages#unread", :as => :mark_contact_message_as_unread |
|
21 |
+ get "admin/subscribers" => "admin_panel#subscribers", :as => :admin_subscribers |
|
22 |
+ get "admin/subscribers/export/cvs" => "admin_panel#export_subscribers_list", :as => :export_subscribers_list |
|
17 | 23 |
get "admin/users" => "admin_panel#users", :as => :admin_users |
18 | 24 |
get "admin/users/:id/make_admin" => "admin_panel#make_admin", :as => :make_admin |
19 | 25 |
get "admin/config" => "admin_panel#site_config", :as => :admin_config |
@@ -27,7 +33,6 @@ RailsWebsiteTemplate::Application.routes.draw do |
||
27 | 33 |
get '/admin/files' => "admin_panel#files", :as => :admin_files |
28 | 34 |
resources :uploads, path: '/admin/files' |
29 | 35 |
|
30 |
- get "start/index" |
|
31 | 36 |
devise_for :users, :skip => [:sessions, :passwords, :confirmations, :registrations] |
32 | 37 |
as :user do |
33 | 38 |
get 'login' => 'devise/sessions#new', :as => :new_user_session |
@@ -109,5 +114,5 @@ RailsWebsiteTemplate::Application.routes.draw do |
||
109 | 114 |
# # (app/controllers/admin/products_controller.rb) |
110 | 115 |
# resources :products |
111 | 116 |
# end |
112 |
- root 'start#index' |
|
117 |
+ |
|
113 | 118 |
end |
@@ -0,0 +1,11 @@ |
||
1 |
+class CreateSubscriptions < ActiveRecord::Migration |
|
2 |
+ def change |
|
3 |
+ create_table :subscriptions do |t| |
|
4 |
+ t.string :first_name |
|
5 |
+ t.string :last_name |
|
6 |
+ t.string :email |
|
7 |
+ |
|
8 |
+ t.timestamps |
|
9 |
+ end |
|
10 |
+ end |
|
11 |
+end |
@@ -11,7 +11,7 @@ |
||
11 | 11 |
# |
12 | 12 |
# It's strongly recommended that you check this file into your version control system. |
13 | 13 |
|
14 |
-ActiveRecord::Schema.define(version: 20141101234157) do |
|
14 |
+ActiveRecord::Schema.define(version: 20150105022653) do |
|
15 | 15 |
|
16 | 16 |
# These are extensions that must be enabled in order to support this database |
17 | 17 |
enable_extension "plpgsql" |
@@ -71,6 +71,14 @@ ActiveRecord::Schema.define(version: 20141101234157) do |
||
71 | 71 |
t.string "server_email" |
72 | 72 |
end |
73 | 73 |
|
74 |
+ create_table "subscriptions", force: true do |t| |
|
75 |
+ t.string "first_name" |
|
76 |
+ t.string "last_name" |
|
77 |
+ t.string "email" |
|
78 |
+ t.datetime "created_at" |
|
79 |
+ t.datetime "updated_at" |
|
80 |
+ end |
|
81 |
+ |
|
74 | 82 |
create_table "uploads", force: true do |t| |
75 | 83 |
t.string "title" |
76 | 84 |
t.string "file" |
@@ -6,7 +6,7 @@ Feature: Admin Panel |
||
6 | 6 |
|
7 | 7 |
Background: |
8 | 8 |
Given the website is configured |
9 |
- And the following blog_post list |
|
9 |
+ And the following list of blog posts |
|
10 | 10 |
| title | content | published | description | slug | |
11 | 11 |
| Hello World | Welcome to the website | true | First Post | hello_world | |
12 | 12 |
| Test 001 | 1 2 3 testing | true | Testing the website | test_001 | |
@@ -6,7 +6,7 @@ Feature: Blog Posts |
||
6 | 6 |
|
7 | 7 |
Background: |
8 | 8 |
Given the website is configured |
9 |
- And the following blog_post list |
|
9 |
+ And the following list of blog posts |
|
10 | 10 |
| title | content | published | description | slug | |
11 | 11 |
| Hello World | Welcome to the website | true | First Post | hello_world | |
12 | 12 |
| Test 001 | 1 2 3 testing | true | Testing the website | test_001 | |
@@ -13,8 +13,8 @@ Feature: Contact Messages |
||
13 | 13 |
Given the website is configured |
14 | 14 |
|
15 | 15 |
Scenario: Send Contact Message as a visitor |
16 |
- Given I go to the homepage |
|
17 |
- When I go to the contact page |
|
16 |
+ Given I visit the homepage |
|
17 |
+ When I click in the link "Contact" |
|
18 | 18 |
Then the page should have a "form" called "new_contact_message" |
19 | 19 |
And I fill in "contact_message_email" with "yo@website.com" |
20 | 20 |
And I fill in "contact_message_title" with "Hello Webmaster" |
@@ -0,0 +1,50 @@ |
||
1 |
+@focus |
|
2 |
+Feature: Email Subscription |
|
3 |
+ |
|
4 |
+ In order to send newsletters to customers |
|
5 |
+ As an marketing guy |
|
6 |
+ I want to a email subscription button |
|
7 |
+ |
|
8 |
+ Background: |
|
9 |
+ Given the website is configured |
|
10 |
+ And the following subscription list |
|
11 |
+ | first_name | last_name | email | |
|
12 |
+ | Jimy | San | jimysan@website.com | |
|
13 |
+ | John | Doe | john_doe@website.com | |
|
14 |
+ |
|
15 |
+ Scenario: Newsletter subscription form |
|
16 |
+ Given I am not logged in |
|
17 |
+ And I visit the homepage |
|
18 |
+ And I should see "Subscribe to our newsletter" |
|
19 |
+ And I fill in "subscription_first_name" with "Monty" |
|
20 |
+ And I fill in "subscription_last_name" with "Cantsin" |
|
21 |
+ And I fill in "subscription_email" with "monty_cantsin@canada.com" |
|
22 |
+ And I click in the button "submit_subscription" |
|
23 |
+ Then I should see "Thanks for subscribing to our newsletter" |
|
24 |
+ And "monty_cantsin@canada.com" should receive an email with subject "Thanks for subscribing" |
|
25 |
+ |
|
26 |
+ Scenario: Admin panel email subscription list |
|
27 |
+ Given I am logged in as admin |
|
28 |
+ And I go to the admin dashboard |
|
29 |
+ And I click in the link "Subscribers" |
|
30 |
+ Then I should see "Jimy San" |
|
31 |
+ And I should see "jimysan@website.com" |
|
32 |
+ And I should see "John Doe" |
|
33 |
+ And I should see "john_doe@website.com" |
|
34 |
+ |
|
35 |
+ Scenario: Export subscription list as a CVS file |
|
36 |
+ Given I am logged in as admin |
|
37 |
+ And I go to the subscribers page |
|
38 |
+ When I click in the link "Export CVS" |
|
39 |
+ Then I should see "Jimy,San,jimysan@website.com," |
|
40 |
+ And I should see "John,Doe,john_doe@website.com" |
|
41 |
+ |
|
42 |
+ |
|
43 |
+ # 1. Create subscription model |
|
44 |
+ # 2. Create subscription controller |
|
45 |
+ # 3. Create subscription form view helper |
|
46 |
+ # 4. Define subscribers method in admin controller |
|
47 |
+ # 5. Create subscribers view |
|
48 |
+ # 6. Define Export to CVS method in admin controller |
|
49 |
+ # 7. Hookup the mailchimp API and send subscriber after subscription |
|
50 |
+ |
@@ -1,4 +1,3 @@ |
||
1 |
-@focus |
|
2 | 1 |
Feature: Maintenance Mode |
3 | 2 |
|
4 | 3 |
In order to change things in the website |
@@ -1,9 +1,9 @@ |
||
1 | 1 |
include Warden::Test::Helpers |
2 | 2 |
|
3 |
-Given /^the following (.+) list ?$/ do |factory, table| |
|
3 |
+Given /^the following list of blog posts?$/ do |table| |
|
4 | 4 |
user = FactoryGirl.create(:user) |
5 | 5 |
table.hashes.each do |hash| |
6 |
- post = FactoryGirl.create(factory, hash) |
|
6 |
+ post = FactoryGirl.create("blog_post", hash) |
|
7 | 7 |
post.author = user |
8 | 8 |
post.save |
9 | 9 |
end |
@@ -15,9 +15,6 @@ Given /^I have blog posts titled (.+)$/ do |titles| |
||
15 | 15 |
end |
16 | 16 |
end |
17 | 17 |
|
18 |
-When /^I go to (.+)$/ do |page_name| |
|
19 |
- path_to(page_name) |
|
20 |
-end |
|
21 | 18 |
|
22 | 19 |
Then(/^The current url should be "(.*?)"$/) do |arg1| |
23 | 20 |
uri = URI.parse(current_url) |
@@ -14,3 +14,25 @@ end |
||
14 | 14 |
Given(/^Maintenance mode is activated$/) do |
15 | 15 |
Info.last.update(maintenance_mode: true, maintenance_title: 'Website under maintenance', maintenance_message: 'Please check back soon') |
16 | 16 |
end |
17 |
+ |
|
18 |
+Given /^the following (.+) list ?$/ do |factory, table| |
|
19 |
+ table.hashes.each do |hash| |
|
20 |
+ FactoryGirl.create(factory, hash) |
|
21 |
+ end |
|
22 |
+end |
|
23 |
+ |
|
24 |
+Then(/^spit out the page HTML$/) do |
|
25 |
+ puts page.html |
|
26 |
+end |
|
27 |
+ |
|
28 |
+When /^I go to (.+)$/ do |page_name| |
|
29 |
+ path_to(page_name) |
|
30 |
+end |
|
31 |
+ |
|
32 |
+Given /^I visit the "(.*)"/ do |place| |
|
33 |
+ visit "/#{place}" |
|
34 |
+end |
|
35 |
+ |
|
36 |
+When /^I visit the homepage$/ do |
|
37 |
+ visit "" |
|
38 |
+end |
@@ -25,6 +25,9 @@ module NavigationHelpers |
||
25 | 25 |
when/the admin blog posts page/ |
26 | 26 |
visit admin_posts_path |
27 | 27 |
|
28 |
+ when/the subscribers page/ |
|
29 |
+ visit admin_subscribers_path |
|
30 |
+ |
|
28 | 31 |
else |
29 | 32 |
raise "Can't find mapping from \"#{page_name}\" to a path." |
30 | 33 |
end |
@@ -34,5 +34,11 @@ FactoryGirl.define do |
||
34 | 34 |
website_link 'http://localhost:3000' |
35 | 35 |
end |
36 | 36 |
|
37 |
+ factory :subscription do |f| |
|
38 |
+ f.first_name "foo" |
|
39 |
+ f.last_name "bar" |
|
40 |
+ f.email "foobar@website.com" |
|
41 |
+ end |
|
42 |
+ |
|
37 | 43 |
end |
38 | 44 |
|
@@ -0,0 +1,9 @@ |
||
1 |
+require 'test_helper' |
|
2 |
+ |
|
3 |
+class SubscriptionControllerTest < ActionController::TestCase |
|
4 |
+ test "should get create" do |
|
5 |
+ get :create |
|
6 |
+ assert_response :success |
|
7 |
+ end |
|
8 |
+ |
|
9 |
+end |
@@ -0,0 +1,11 @@ |
||
1 |
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html |
|
2 |
+ |
|
3 |
+one: |
|
4 |
+ first_name: MyString |
|
5 |
+ last_name: MyString |
|
6 |
+ email: MyString |
|
7 |
+ |
|
8 |
+two: |
|
9 |
+ first_name: MyString |
|
10 |
+ last_name: MyString |
|
11 |
+ email: MyString |
@@ -0,0 +1,4 @@ |
||
1 |
+require 'test_helper' |
|
2 |
+ |
|
3 |
+class SubscriptionHelperTest < ActionView::TestCase |
|
4 |
+end |
@@ -0,0 +1,7 @@ |
||
1 |
+require 'test_helper' |
|
2 |
+ |
|
3 |
+class SubscriptionTest < ActiveSupport::TestCase |
|
4 |
+ # test "the truth" do |
|
5 |
+ # assert true |
|
6 |
+ # end |
|
7 |
+end |